package com.wing.product.controller.admin;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wing.common.enums.MaintenanceEnum;
import com.wing.common.exception.BusinessException;
import com.wing.device.model.entity.DeviceModel;
import com.wing.device.service.DeviceModelService;
import com.wing.device.service.DeviceTypeService;
import com.wing.dict.model.entity.DictLabel;
import com.wing.dict.service.DictLabelService;
import com.wing.product.model.entity.ProAbnormalCause;
import com.wing.product.model.entity.ProductItem;
import com.wing.product.model.response.ProcessInfoVO;
import com.wing.product.model.response.ProductTypeVO;
import com.wing.product.service.ProAbnormalCauseService;
import com.wing.product.service.ProductItemService;
import com.wing.res.model.response.DeviceOrWorkVo;
import com.wing.res.model.response.ResProductDrawPicVo;
import com.wing.web.annotation.RequestObjectFieldIgnore;
import com.wing.common.utils.JsonResult;
import com.wing.common.utils.PageResult;
import com.wing.product.model.entity.ProcessInfo;
import com.wing.product.model.request.ProcessInfoForm;
import com.wing.product.service.ProcessInfoService;
import com.wing.web.db.config.util.DynamicDataSource;
import com.wing.web.excel.DownExcelUtil;
import com.wing.web.excel.ExcelUtil;
import com.wing.web.excel.ProcessInfoExcelIn;
import com.wing.web.utils.JwtUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author
 */
@Validated
@Api(value = "Admin-工序管理", tags = "#/product/processInfo")
@RestController("processInfoController")
@RequestMapping("product/admin/processInfo")
@RequiredArgsConstructor
public class ProcessInfoController {

    private final ProcessInfoService processInfoService;
    private final ProductItemService productItemService;
    private final DeviceTypeService deviceTypeService;
    private final DeviceModelService deviceModelService;
    private final DictLabelService dictLabelService;
    private final ProAbnormalCauseService proAbnormalCauseService;

    @ApiOperation(value = "查询所有工序", notes = "搜索")
    @GetMapping("/list")
    public PageResult<ProcessInfoVO> list(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer limit,
            @RequestParam(defaultValue = "create_time") String sort,
            @RequestParam(defaultValue = "asc") String order,
            @RequestParam(value = "productTypeId", required = false) Long productTypeId,
            @RequestParam(value = "type", required = false) Long type,
            @RequestParam(value = "code", required = false) String code,
            @RequestParam(value = "roomInfoId", required = false) Long roomInfoId,
            @RequestParam(value = "name", required = false) String name,
            @RequestParam(value = "notInListIds", required = false) String notInListIds
    )
    {
        Page<ProcessInfoVO> pg = new Page<>(page, limit);
        Map<String,Object> map = new HashMap<>();
        map.put("order", order);
        map.put("productTypeId", productTypeId);
        map.put("type", type);
        if(StringUtils.isNotBlank(name)){
            map.put("name", name);
        }

        if(StringUtils.isNotBlank(code)){
            map.put("code", code);
        }
        if (StringUtils.isNotBlank(notInListIds)) {
            String[] lists = notInListIds.split(",");
            map.put("notInListIds", lists);
        }
        String databaseUser = DynamicDataSource.USER_PREFIX;
        if (StringUtils.isNotBlank(DynamicDataSource.name.get())) {
            databaseUser = databaseUser + "-" + DynamicDataSource.name.get();
        }
        map.put("databaseUser", databaseUser);
        //查询已经存在的工序
        IPage<ProcessInfoVO> list = processInfoService.pageList4app(pg, map);
        if (CollectionUtil.isNotEmpty(list.getRecords())) {
            for (ProcessInfoVO record : list.getRecords()) {
                record.setQualityTypeName(record.getQualityRateName());
                record.setQualityType(record.getQualityRate());
                List<ProductItem> productItems = productItemService.listItem(record.getId());
                record.setProductItems(productItems);
            }
        }
        if (type != null) {
            if (1 == type) {
                Map<String,Object> newMap = new HashMap<>();
                newMap.put("order", order);
                newMap.put("databaseUser", databaseUser);
                //查询所有工序
                Page<ProcessInfoVO> pg2 = new Page<>(page, limit);
                IPage<ProcessInfoVO> allList = processInfoService.pageList4app(pg2, newMap);
                for (ProcessInfoVO all : allList.getRecords()) {
                    List<ProductItem> productItems = productItemService.listItem(all.getId());
                    all.setProductItems(productItems);
                    for (ProcessInfoVO listRecord : list.getRecords()) {
                        if (all.getId().equals(listRecord.getId())) {
                            all.setElect(true);
                        }
                    }
                }
                return new PageResult<>(allList.getRecords(), allList.getTotal());
            }
        }
        return new PageResult<>(list.getRecords(), list.getTotal());
    }


    @ApiOperation(value = "添加工序", notes = "添加")
    @RequestObjectFieldIgnore({"id", "createTime", "remark"})
    @PostMapping("/add")
    public JsonResult add(@Validated(ProcessInfoForm.Add.class) ProcessInfoForm processInfoForm) {
        Map<String,Object> map = new HashMap<>();
        String databaseUser = DynamicDataSource.USER_PREFIX;
        if (StringUtils.isNotBlank(DynamicDataSource.name.get())) {
            databaseUser = databaseUser + "-" + DynamicDataSource.name.get();
        }
        map.put("databaseUser", databaseUser);
        map.put("nodeCodes", processInfoForm.getNodeCodes());
        List<ProcessInfoVO> list = processInfoService.list4app(map);
        if (!list.isEmpty()) {
            return JsonResult.fail("添加失败,工序编码重复");
        }
        if (processInfoService.add(processInfoForm) > 0) {
            return JsonResult.success("添加成功");
        }
        return JsonResult.fail("添加失败");
    }


    @ApiOperation(value = "修改工序", notes = "修改")
    @PutMapping("/update")
    public JsonResult update(@Validated(ProcessInfoForm.Update.class) ProcessInfoForm processInfoForm) {
        ProcessInfo processInfo = processInfoService.getById(processInfoForm.getId());
        if (processInfo == null) {
            return JsonResult.fail("修改失败！");
        }
        CopyOptions copyOptions = CopyOptions.create()
                .setEditable(ProcessInfo.class)
                .setIgnoreError(true)
                .setIgnoreNullValue(true);
        BeanUtil.copyProperties(processInfoForm, processInfo, copyOptions);
        if (processInfoService.updateById(processInfo)) {
            return JsonResult.success("修改成功！");
        }
        return JsonResult.fail("修改失败！");
    }

    @ApiOperation(value = "修改工序", notes = "修改")
    @PutMapping("/updateProductType")
    public JsonResult updateProductType(@Validated(ProcessInfoForm.Update.class) ProcessInfoForm processInfoForm) {

        return JsonResult.success("修改成功！");
    }


    @ApiOperation(value = "删除工序", notes = "删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "processInfoId", value = "id", required = true, dataType = "Integer", paramType = "path")
    })
    @DeleteMapping("/{id}")
    public JsonResult delete(@PathVariable("id") Long processInfoId) {
        if (processInfoService.removeById(processInfoId)) {
            return JsonResult.success("删除成功");
        }
        return JsonResult.fail("删除失败");
    }

    @ApiOperation(value = "根据id查询工序", notes = "查询")
    @GetMapping("/selectProcessInfoById")
    public JsonResult<ProcessInfo> selectProcessInfoById(@RequestParam(value = "id") Long id) {
        ProcessInfo processInfo = processInfoService.getById(id);
        return JsonResult.success(processInfo);

    }

    @ApiOperation(value = "查询所有工序", notes = "查询")
    @GetMapping("/getAllProcessInfo")
    public JsonResult<List<ProcessInfo>> getAllProcessInfo() {
        QueryWrapper<ProcessInfo> wrapper = new QueryWrapper<>();
        wrapper.select("id", "node_names");
        List<ProcessInfo> list = processInfoService.list(wrapper);
        return JsonResult.success(list);

    }

    /**
     * 下载工序录入excel模板
     */
    @ApiOperation(value = "下载工序录入excel模板")
    @GetMapping("/template")
    public void template(HttpServletResponse response, HttpServletRequest request) throws IOException {
        // 字典数据

        //"工序编码(*)", "物料编码(*)", "工序号（*）", "工序名称(*)","工序内容","工序设备",
        // "夹具编号(*)", "量具(*)", "工时定额(*)","工序类型","工序性质","是否支持委外",
        // "是否需要质检","检测频率"
        String[] headerArr = {"工序编码(*)", "物料编码(*)", "工序号(*)","工序名称(*)",
                "工序内容","工位性质","工种", "设备类型","夹具编号", "量具","报工单位", "工时定额(分钟)","OK工资定额(元)","NG工资定额(元)","报修工资定额","工序类型",
                "工序性质","是否支持委外","是否需要质检","检测频率","人员工种"};
        List<String[]> downData = new ArrayList<>();
        List<String> indexArr = new ArrayList<>();
        StringBuffer tempStr = new StringBuffer();

        List<DictLabel> dictLabelList = dictLabelService.list(null);

        //工位性质
        String[] workInfo = new String[]{"设备工位", "人工工位"};
        for (String yesNodatum : workInfo) {
            tempStr.append(yesNodatum).append(",");
        }
        tempStr.delete(tempStr.length() - 1, tempStr.length());
        downData.add(workInfo);
        tempStr.delete(0, tempStr.length());
        indexArr.add("5");

        //工种
        List<DeviceOrWorkVo> fessionlist = deviceModelService.fessionlist();
        if(CollectionUtil.isNotEmpty(fessionlist)){
            for (DeviceOrWorkVo vo : fessionlist) {
                tempStr.append(vo.getDeviceName()).append(",");
            }
            tempStr.delete(tempStr.length()-1, tempStr.length());
            downData.add(tempStr.toString().split(","));
            tempStr.delete(0,tempStr.length());
            indexArr.add("6");
        }

        //设备类型
        QueryWrapper<DeviceModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted",0);
        List<DeviceModel> deviceModels = deviceModelService.list(queryWrapper);
        if(CollectionUtil.isNotEmpty(deviceModels)){
            for (DeviceModel type : deviceModels) {
                tempStr.append(type.getName()).append(",");
            }
            tempStr.delete(tempStr.length()-1, tempStr.length());
            downData.add(tempStr.toString().split(","));
            tempStr.delete(0,tempStr.length());
            indexArr.add("7");
        }

        List<DictLabel> typeList = dictLabelList.stream().filter(t -> "process_node_type".equals(t.getDictType())).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(typeList)){
            for (DictLabel type : typeList) {
                tempStr.append(type.getLabelName()).append(",");
            }
            tempStr.delete(tempStr.length()-1, tempStr.length());
            downData.add(tempStr.toString().split(","));
            tempStr.delete(0,tempStr.length());
            indexArr.add("15");
        }

        List<DictLabel> natureList = dictLabelList.stream().filter(t -> "process_nature".equals(t.getDictType())).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(natureList)){
            for (DictLabel nature : natureList) {
                tempStr.append(nature.getLabelName()).append(",");
            }
            tempStr.delete(tempStr.length()-1, tempStr.length());
            downData.add(tempStr.toString().split(","));
            tempStr.delete(0,tempStr.length());
            indexArr.add("16");
        }

        String[] yesNodata = new String[]{"是", "否"};
        for (String yesNodatum : yesNodata) {
            tempStr.append(yesNodatum).append(",");
        }
        tempStr.delete(tempStr.length() - 1, tempStr.length());
        downData.add(yesNodata);
        tempStr.delete(0, tempStr.length());
        indexArr.add("17");


        for (String yesNodatum : yesNodata) {
            tempStr.append(yesNodatum).append(",");
        }
        tempStr.delete(tempStr.length() - 1, tempStr.length());
        downData.add(yesNodata);
        tempStr.delete(0, tempStr.length());
        indexArr.add("18");

        List<DictLabel> rateList = dictLabelList.stream().filter(t -> "process_quality_rate".equals(t.getDictType())).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(rateList)){
            for (DictLabel rate : rateList) {
                tempStr.append(rate.getLabelName()).append(",");
            }
            tempStr.delete(tempStr.length()-1, tempStr.length());
            downData.add(tempStr.toString().split(","));
            tempStr.delete(0,tempStr.length());
            indexArr.add("19");
        }


        if(CollectionUtil.isNotEmpty(fessionlist)){
            for (DeviceOrWorkVo vo : fessionlist) {
                tempStr.append(vo.getDeviceName()).append(",");
            }
            tempStr.delete(tempStr.length()-1, tempStr.length());
            downData.add(tempStr.toString().split(","));
            tempStr.delete(0,tempStr.length());
            indexArr.add("20");
        }
        DownExcelUtil.createExcelTemplate(response, request, "工序导入模板", Arrays.asList(headerArr), downData, indexArr);
    }


    /**
     * 导入工序excel
     */
    @ApiOperation(value = "导入工序excel")
    @PostMapping("/importExcel")
    public JsonResult importExcel(HttpServletRequest request, @RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return JsonResult.fail("导入文件为空！");
        }
        try {
            //获取原始的文件名
            ExcelUtil<ProcessInfoExcelIn> reader = new ExcelUtil<>();
            InputStream is = file.getInputStream();
            List<ProcessInfoExcelIn> list = reader.read(is, ProcessInfoExcelIn.class);
            if (CollectionUtils.isEmpty(list)) {
                return JsonResult.fail("请在表格中添加数据！");
            }
            processInfoService.importExcel(list);
        } catch (BusinessException e) {
            return JsonResult.fail(e.getCode(), e.getMessage());
        } catch (Exception e) {
            return JsonResult.exception("导入文件异常！异常信息:" + e.getMessage());
        }
        return JsonResult.success("导入成功！");
    }

    /**
     * 添加质检异常设置
     */
    @ApiOperation(value = "添加-质检异常设置")
    @PostMapping("/addQualitySet")
    public JsonResult addQualitySet(@RequestBody ProAbnormalCause causes) {
        if (ObjectUtil.isEmpty(causes)) {
            return JsonResult.fail("未添加质检异常信息!");
        }
        causes.setCreator(JwtUtils.getLoginUserId());
        causes.setCreatorName(JwtUtils.getLoginUsername());
        causes.setCreateTime(LocalDateTime.now());
        causes.setStatus(MaintenanceEnum.errorStatus.ZC.getCode());
        boolean save = proAbnormalCauseService.save(causes);
        if(save){
            return JsonResult.success("添加成功！");
        }
        return JsonResult.fail("添加失败！");
    }


    /**
     * 添加质检异常设置
     */
    @ApiOperation(value = "修改-质检异常设置")
    @PostMapping("/updateQualitySet")
    public JsonResult updateQualitySet(@RequestBody ProAbnormalCause causes) {
        ProAbnormalCause byId = this.proAbnormalCauseService.getById(causes.getId());
        if (ObjectUtil.isEmpty(byId)) {
            return JsonResult.fail("未查询到质检异常信息!");
        }
        byId.setModifier(JwtUtils.getLoginUserId());
        byId.setModifierName(JwtUtils.getLoginUsername());
        byId.setUpdateTime(LocalDateTime.now());
        boolean updated = proAbnormalCauseService.updateById(causes);
        if(updated){
            return JsonResult.success("修改成功！");
        }
        return JsonResult.fail("修改失败！");
    }

    /**
     * 添加质检异常设置
     */
    @ApiOperation(value = "查询-质检异常信息")
    @GetMapping("/abnormalCauseList")
    public PageResult<ProAbnormalCause> abnormalCauseList(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer limit,
            @RequestParam(defaultValue = "create_time") String sort,
            @RequestParam(defaultValue = "asc") String order,
            @RequestParam("processId") String processId,
            String name,
            String code
    ) {

        Page<ProAbnormalCause> pg = new Page<>(page, limit);
        Map<String,Object> map = new HashMap<>();
        map.put("name",name);
        map.put("code",code);
        map.put("processId",processId);
        String databaseUser = DynamicDataSource.USER_PREFIX;
        if (StringUtils.isNotBlank(DynamicDataSource.name.get())) {
            databaseUser = databaseUser + "-" + DynamicDataSource.name.get();
        }
        map.put("databaseUser", databaseUser);
        //获取工序的质检异常信息
        IPage<ProAbnormalCause> list = this.proAbnormalCauseService.getAbnormalCauseList(pg,map);
        if (CollectionUtils.isNotEmpty(list.getRecords())){
            for (ProAbnormalCause record : list.getRecords()) {
                record.setStatusName(MaintenanceEnum.errorStatus.getNameByCode(record.getStatus()));
            }
        }
        return new PageResult<>(list.getRecords(), list.getTotal());
    }


    /**
     * 添加质检异常设置
     */
    @ApiOperation(value = "启用/停用-质检异常信息")
    @PostMapping("/openOrClose/{id}/{status}")
    public JsonResult openOrClose(@PathVariable("id") Long id,@PathVariable("status")String status) {
        ProAbnormalCause byId = this.proAbnormalCauseService.getById(id);
        if (ObjectUtil.isEmpty(byId)) {
            return JsonResult.fail("未查询到质检异常信息!");
        }
        byId.setModifier(JwtUtils.getLoginUserId());
        byId.setModifierName(JwtUtils.getLoginUsername());
        byId.setUpdateTime(LocalDateTime.now());
        byId.setStatus(status);
        boolean updated = this.proAbnormalCauseService.updateById(byId);
        if (updated){
            return JsonResult.success("启用/禁用成功！");
        }
        return JsonResult.fail("操作失败");
    }



}
